/* shttpd - TCP/IP listening sockets associated with tasks
   Copyright (C) 2018 Ariadne Devos

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */

#ifndef _sHT_ACCEPT_H
#define _sHT_ACCEPT_H

#include <sHT/task.h>

struct sHT_worker;
struct sHT_task_stream;

/* A TCP/IP listening socket */
struct sHT_passive
{
	int fd;
	int max_accept_iterations;
};

struct sHT_task_accept
{
	struct sHT_task task;
	struct sHT_passive accept;
};

/* Allocate a task for a connection that might be returned by
   accept(2). NULL is considered to be an allocation failure.

   It is up to this function to set worker->flags error flags. */
__attribute__((warn_unused_result))
__attribute__((nonnull (1, 2)))
struct sHT_task_stream *
sHT_accept_subtask(struct sHT_worker *worker, struct sHT_task_accept *task);

/* subtask has been allocated by sHT_accept_subtask, with the listening socket
   being task, but no connection has been accepted by accept(2). Free subtask.
 */
__attribute__((nonnull (1, 2, 3)))
void
sHT_accept_abort(struct sHT_worker *worker, struct sHT_task_accept *task, struct sHT_task_stream *subtask);

/* child->stream.fd is set. task can choose what to do with it. task is not
   automatically scheduled in case of possible IO. child has been allocated by
   sHT_accept_subtask. */
__attribute__((nonnull (1, 2, 3)))
void
sHT_accept_logic(struct sHT_worker *worker, struct sHT_task_accept *task, struct sHT_task_stream *child);

__attribute__((nonnull (1, 2)))
void
sHT_accept_task(struct sHT_worker *worker, struct sHT_task_accept *task);

#endif
